package blogs.eidos.cloud.framework.core.interceptor;

import com.alibaba.druid.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import net.bigdata.cloud.framework.common.api.HttpCodeEnum;
import net.bigdata.cloud.framework.constant.CommonConstant;
import net.bigdata.cloud.framework.constant.CoreConstant;
import net.bigdata.cloud.framework.core.annotation.AuthIgnore;
import net.bigdata.cloud.framework.core.annotation.AuthShare;
import net.bigdata.cloud.framework.shiro.cache.JwtTokenRedisService;
import net.bigdata.cloud.framework.shiro.vo.LoginUser;
import net.bigdata.cloud.framework.util.LoginUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @author ： Eidos
 * @date ：Created in 2021/4/12
 * @description：
 * @modified By：
 * @version: 1.0
 */
@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtTokenRedisService jwtTokenRedisService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        HandlerMethod handlerMethod = null;
        try {
            handlerMethod = (HandlerMethod) handler;
        } catch (Exception e) {
            response.setStatus(HttpCodeEnum.NOT_FOUND.getCode());
            return false;
        }

        Method method = handlerMethod.getMethod();

        AuthIgnore ignoreAuthMethod = method.getAnnotation(AuthIgnore.class);
        //注解不需要验证token
        if (handler instanceof HandlerMethod && null != ignoreAuthMethod) {
            return true;
        }

        // 注解 token可分享
        AuthShare authShareMethod = method.getAnnotation(AuthShare.class);
        String token = request.getHeader(CoreConstant.TOKEN_HEADER_STRING);
        if (null != authShareMethod) {
            if (!StringUtils.isEmpty(token) && token.startsWith(CoreConstant.TOKEN_PREFIX)) {
                LoginUser loginUser = LoginUtil.getLoginUser();
                request.setAttribute(CoreConstant.CURRENT_USER, loginUser);
            }
            return true;
        }
        // nk 不需要验证
        if (request.getServletPath().contains(CommonConstant.API_NO_KEY)) {
            return true;
        }
        if (StringUtils.isEmpty(token) || !token.startsWith(CoreConstant.TOKEN_PREFIX)) {
            log.debug("{} : Unknown token", request.getServletPath());
            response.setStatus(HttpCodeEnum.ACCESS_DENIED_ERROR.getCode());
            response.getWriter().print(HttpCodeEnum.ACCESS_DENIED_ERROR.getMessage());
            return false;
        }
        LoginUser loginUser = jwtTokenRedisService.getLoginUserByToken(token);
        if (null != loginUser) {
            return Boolean.TRUE;
        } else {
            throw new AuthenticationException(HttpCodeEnum.ACCESS_DENIED_ERROR.getMessage());
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}
